﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using SistemaDeBastanteodePoderes.Persistencia;
using SistemaDeBastanteodePoderes.Dominio;

namespace SistemaDeBastanteodePoderes.Pruebas.DAO
{
    [TestFixture]
    public class Test_H2_2_RepresentanteDAO
    {
        ITipoDocumentoDAO tipoDocumentoDAO = null;
        IClienteDAO clienteDAO = null;
        TipoDocumento tipoDocumento = null;
        Cliente cliente = null;
        ITipoEmpresaDAO tipoEmpresaDAO = null;
        TipoEmpresa tipoEmpresa = null;
        IRepresentanteDAO representanteDAO = null;
        Representante representanteCreado = null;

        [TestFixtureSetUp]
        public void InicializarPruebas()
        {
            tipoDocumentoDAO = new Persistencia.NH.TipoDocumentoDAO(); // NHibernate  
            clienteDAO = new Persistencia.NH.ClienteDAO(); // NHibernate
            tipoEmpresaDAO = new Persistencia.NH.TipoEmpresaDAO(); //NHibernate
            representanteDAO = new Persistencia.NH.RepresentanteDAO(); //NHibernate
            foreach (Representante representante in representanteDAO.ListarTodos())
                representanteDAO.Eliminar(representante);
            tipoEmpresa = tipoEmpresaDAO.Crear(new TipoEmpresa() { Abreviacion = "SAC", Descripcion = "SOCIEDAD ANONIMA CERRADA" });
            cliente = clienteDAO.Crear(new Cliente() { nroRUC = "101", razSocial = "EMPRESA 101", fecIniOperaciones = DateTime.Now, tipEmpresa = tipoEmpresa, cntEmpleados = 99 });
            tipoDocumento = tipoDocumentoDAO.Crear(new TipoDocumento() { TipCorto = "TD1", TipLargo = "TIPO DOCUMENTO 1" });
        }

        [Test]
        public void Test1_Crear()
        {
            // 1. Validar que ocurra un error al intentar crear un representante con un dato nulo
            Representante representanteACrear = new Representante();
            representanteACrear.Empresa      = cliente;
            representanteACrear.NroDoc       = "1234567890";
            representanteACrear.Nombres      = "NOMBRE 01";
            representanteACrear.Apellidos    = "APELLIDO 01";
            representanteACrear.Cargo        = "CARGO 01";
            representanteACrear.GruBastanteo = "A";
            representanteACrear.TipDoc = null;
            Assert.Catch<Exception>(delegate
            {
                representanteCreado = representanteDAO.Crear(representanteACrear);
            });

            // 2. Validar que se cree un representante correctamente (sin error)
            representanteACrear.TipDoc = tipoDocumento;
            Assert.DoesNotThrow(delegate
            {
                representanteCreado = representanteDAO.Crear(representanteACrear);
            });

            // 3. Validar que el representante creado no sea nulo, tenga un código mayor a 0 y el tipo de empresa sea el ingresado
            Assert.IsNotNull(representanteCreado);
            Assert.Greater(representanteCreado.Codigo, 0);
            Assert.AreEqual(representanteCreado.Empresa.Codigo, cliente.Codigo);
        }
        [Test]
        public void Test2_Obtener()
        {
            Representante representanteObtenido = null;
            // 1. Validar que se retorne nulo al obtener un representante inexistente
            Assert.DoesNotThrow(delegate
            {
                representanteObtenido = representanteDAO.Obtener(1000);
            });
            Assert.IsNull(representanteObtenido);
            // 2. Validar que se obtenga el representante creado satisfactoriamente
            Assert.DoesNotThrow(delegate
            {
                representanteObtenido = representanteDAO.Obtener(representanteCreado.Codigo);
            });
            Assert.IsNotNull(representanteObtenido);

            // 3. Validar que el nro.doc obtenido sea el creado anteriormente
            Assert.AreEqual(representanteObtenido.NroDoc, "1234567890");
        }
        [Test]
        public void Test3_Modificar()
        {
            Representante representanteAModificar = representanteDAO.Obtener(representanteCreado.Codigo);
            representanteAModificar.Nombres = "NOMBRE MODIF";
            representanteAModificar.Apellidos = "APELLIDO MODIF";
            representanteAModificar.TipDoc = null;
            Representante representanteModificado = null;
            // 1. Validar que ocurrar un error al intentar modificar el representante con un tipo de empresa nulo
            Assert.Catch<Exception>(delegate
            {
                representanteModificado = representanteDAO.Modificar(representanteAModificar);
            });
            // 2. Validar que se modifique correctamente el representante
            representanteAModificar.TipDoc = tipoDocumento;
            Assert.DoesNotThrow(delegate
            {
                representanteModificado = representanteDAO.Modificar(representanteAModificar);
            });
            // 3. Validar que el representante modificado no sea nulo, tenga la apellidos, nombres y codigo de empresa
            Assert.IsNotNull(representanteModificado);
            Assert.AreEqual(representanteAModificar.Apellidos, representanteModificado.Apellidos);
            Assert.AreEqual(representanteAModificar.Nombres, representanteModificado.Nombres);
            Assert.AreEqual(representanteAModificar.Empresa.Codigo, representanteModificado.Empresa.Codigo);
        }
        [Test]
        public void Test4_Eliminar()
        {
            Representante representanteAEliminar = representanteDAO.Obtener(representanteCreado.Codigo);
            // 1. Validar que ocurre un error si se intenta eliminar un representante nulo
            Assert.Catch<Exception>(delegate
            {
                representanteDAO.Eliminar(null);
            });
            // 2. Validar que se elimina correctamente el representante creado
            Assert.DoesNotThrow(delegate
            {
                representanteDAO.Eliminar(representanteAEliminar);
            });
            // 3. Validar que luego de eliminado se retorne nulo al obtenerlo
            Representante representanteEliminado = representanteDAO.Obtener(representanteCreado.Codigo);
            Assert.IsNull(representanteEliminado);

        }
        [Test]
        public void Test5_Listar()
        {
            representanteDAO.Crear(new Representante() { TipDoc = tipoDocumento, NroDoc = "11111111", Nombres = "NOMBRE 11", Apellidos = "APELLIDOS 11", Cargo = "CARGO 11", GruBastanteo = "A", Empresa = cliente });
            representanteDAO.Crear(new Representante() { TipDoc = tipoDocumento, NroDoc = "22222222", Nombres = "NOMBRE 22", Apellidos = "APELLIDOS 22", Cargo = "CARGO 11", GruBastanteo = "A", Empresa = cliente });
            // 1. Validar que se listen los representante existentes exitosamente
            ICollection<Representante> representantesExistentes = null;
            Assert.DoesNotThrow(delegate
            {
                representantesExistentes = representanteDAO.ListarTodos();
            });
            // 2. Validar que se retornen al menos los 2 representante creados previamente
            Assert.GreaterOrEqual(representantesExistentes.Count, 2);
            // 3. Validar que cada representante obtenido tenga un nro.doc no nulo
            foreach (Representante representante in representantesExistentes)
                Assert.IsNotNull(representante.NroDoc);
        }

        [TestFixtureTearDown]
        public void FinalizarPruebas()
        {
            foreach (Representante representante in representanteDAO.ListarTodos())
                representanteDAO.Eliminar(representante);
            tipoDocumentoDAO.Eliminar(tipoDocumento);
            clienteDAO.Eliminar(cliente);
            tipoEmpresaDAO.Eliminar(tipoEmpresa);
            Persistencia.NH.NHibernateHelper.CerrarFabrica();
        }
    }

}